home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / NRLIBE32.ZIP / EXAMPLE2.C < prev    next >
C/C++ Source or Header  |  1994-12-01  |  9KB  |  254 lines

  1. /****************************************************************************/
  2. /*                                                                          */
  3. /*                     Example 2 of NRLIB32 library use                     */
  4. /*                                                                          */
  5. /*  This program is an example of genetic algoritm for xor net training.    */
  6. /*  A population of nets are tested for xor behavior. Net fitness correspond*/
  7. /*  to inverse of mean quadratic error.                                     */
  8. /*  After all nets are tested , they are ordered according to their fitness */
  9. /*  (first the best or the minimum mean quadratic error).                   */
  10. /*                                                                          */
  11. /*  This is the first generation ; best 1/5 of population procreate and     */
  12. /*  replace other nets (total nets is constant) .                           */
  13. /*  On new population we apply a little random mutations to weights.        */
  14. /*                                                                          */
  15. /*  In this example, application of genetic algoritm is not a classical     */
  16. /*  version, because we don't use binary alphabet for genetic string and    */
  17. /*  we don't apply  crossover operator (sexual procreation).                */
  18. /*                                                                          */
  19. /*  This algoritm is repeated for more generations , and you can see that   */
  20. /*  the net behavior improve.                                               */
  21. /*                                                                          */
  22. /*  This algoritm is slower than EBP , but is useful in tasks that need more*/
  23. /*  complicated fitness evaluation than exactly answers , like ecological   */
  24. /*  tasks.                                                                  */
  25. /*                                                                          */
  26. /*  You must compile this program and link it with NRLIB32.OBJ file.        */
  27. /*  Memory model is large.                                                  */
  28. /*                                                                          */
  29. /****************************************************************************/
  30.  
  31.  
  32.  
  33. # include "nrlib32.h"                 /* Library include                    */
  34. # include <stdio.h>
  35. # include <stdlib.h>
  36. # include <math.h>
  37.  
  38.  
  39. # define TU 500                       /* Max number of nets                 */
  40.  
  41. # define MLIV   2                     /* Max  layer                         */
  42. # define NL0    2                     /* Layer 0 nodes                      */
  43. # define NL1    4                     /* Layer 1 nodes                      */
  44. # define NL2    1                     /* Layer 2 nodes                      */
  45.  
  46. # define NULLL  0L
  47.  
  48. struct un                             /* Fitness list                       */
  49. {
  50.  int   nr;                            /* Net number                         */
  51.  float err;                           /* Mean quadratic error               */
  52. }         un[TU+1];
  53.  
  54.                       /* Buffers for net inputs and output  */
  55. float vinp[NL0+1];
  56. float vout[NL2+1];
  57. float verr[NL2+1];
  58.  
  59. float err[TU+1];                      /* Buffers for net quadratic errors   */
  60.  
  61. int tu=100;                           /* Total default nets                 */
  62.  
  63. int tgen=300;                         /* Total default generations          */
  64.  
  65. int bu;                      /* Buffer for range of best nets that procreate*/
  66.  
  67. char filetrain[]="nettrain.dat";   /* Training file                      */
  68.  
  69.  
  70. float frndab(float a,float b);
  71.  
  72.  
  73. main(int argc, char *argv[])
  74. {
  75.  int i,ge,ta;
  76.  long sss;
  77.  for (i=1;i<argc;i++)
  78.  {
  79.    if (strncmp(argv[i],"/tu=",4) == 0)  {tu=atoi(argv[i]+4);continue;}
  80.    if (strncmp(argv[i],"/tg=",4) == 0)  {tgen=atoi(argv[i]+4);continue;}
  81.    if (strncmp(argv[i],"/h",2) == 0)    {help();exit(0);}
  82.  }
  83.  if (tu > 500) tu=500;
  84.  bu=tu/5;                           /* Range of selection(1/5 of population)*/
  85.  param("fd","0");                   /* No verbose                           */
  86.  time(&sss);srand((int)sss);        /* Init random seed                     */
  87.  initialize();                      /* Create nets                          */
  88.  evolution();                       /* Nets life and evolution              */
  89.  end();
  90. }
  91.  
  92.  
  93. initialize()
  94. {
  95.  int i,j,nu;
  96.  LONG vn[MLIV+1];
  97.  char vf[MLIV+1][10], va[MLIV+1][10];
  98.                  /* Init array for <createallnets> function     */
  99.    vn[0]=NL0;strcpy(vf[0],"f1");strcpy(va[0],"0");
  100.    vn[1]=NL1;strcpy(vf[1],"f5");strcpy(va[1],"0");
  101.    vn[2]=NL2;strcpy(vf[2],"f5");strcpy(va[2],"0");
  102.  
  103.  param("ra","-1");param("rb","1"); /* modify default random weigt generation*/
  104.                  /* Nets creation                               */
  105.  createallnet(tu,MLIV,vn,vf,va);
  106.  
  107.  for (nu=1;nu<=tu;nu++) un[nu].nr=nu;    /* Initialize fitness list         */
  108. }
  109.  
  110.  
  111. evolution()
  112. {
  113.  int ge;
  114.    for (ge=1;ge<=tgen;ge++)      /* Loop for <tgen> generations             */
  115.    {
  116.      netlife() ;                 /* Test all nets                           */
  117.      errshow(ge);                /* Display best performance (min. err)     */
  118.      procreate();                /* New generation (best selected)          */
  119.    }
  120. }
  121.  
  122.  
  123. netlife()
  124. {
  125.  int cv,nu,ret,i,j,stp=0;
  126.  float errq,fout[NL2+1];
  127.    static FILE *fp;
  128.                  /* Open trainer file for input values and      */
  129.                  /* reference output  values                    */
  130.    if (fp == NULLL)
  131.    {
  132.    fp = fopen(filetrain,"r");
  133.    if (fp == NULLL) {printf("Can't open trainer file \r\n");exit(-1);}
  134.    }
  135.  
  136.  /********** Loop for all records of trainer file */
  137.  /* each record = 1 life step */
  138.  while(fscanf(fp,"%f",&vinp[1]) > 0)
  139.  {
  140.                  /* Input values to <vinp> array                */
  141.      for (i=2;i<=NL0;i++)
  142.      {
  143.        ret=fscanf(fp,"%f",&vinp[i]);
  144.        if  (ret <= 0)
  145.        {printf("Error on trainer file \r\n");exit(-1);}
  146.      }
  147.                  /* Reference output values to <fout> array     */
  148.      for (i=1;i<=NL2;i++)
  149.      {
  150.        ret=fscanf(fp,"%f",&fout[i]);
  151.        if  (ret <= 0)
  152.        {printf("Error on trainer file \r\n");exit(-1);}
  153.      }
  154.  
  155.      stp++;                  /* one more life step */
  156.                  /* Apply input to all nets and compute output */
  157.      for (nu=1;nu<=tu;nu++)
  158.      {
  159.        for (i=1;i<=NL2;i++) verr[i]=fout[i]; /*because verr is modified by*/
  160.        errq=compute(nu,vinp,vout,verr);       /*compute function           */
  161.        err[nu]=err[nu]+errq;
  162.      }
  163.  }
  164.  /********** end trainer file loop = end life */
  165.  rewind(fp);
  166.                  /* Average quadratic error                    */
  167.  for (nu=1;nu<=tu;nu++)  err[nu]=err[nu]/stp;
  168.  
  169.                  /* Load fitness list                          */
  170.  for (i=1;i<=tu;i++)  {j=un[i].nr;un[i].err=err[j];err[j]=0;}
  171.  
  172.                  /* Sort list (first best = lowest error)      */
  173.  listsort(un,tu);
  174. }
  175.  
  176. errshow(int ge)
  177. {
  178.    printf("Generation %4d    Lowest error %7.4f   Net %3d \n",
  179.    ge,un[1].err,un[1].nr);
  180. }
  181.  
  182.  
  183. procreate()
  184. {
  185.   int i,j,nu;
  186.   LONG in,tc,jc,node;
  187.   float weigt;
  188.                   /* Clone the bests <bu> nets                */
  189.   for (i=bu+1;i<=tu;i++) copynet(un[rndab(1,bu)].nr,un[i].nr);
  190.  
  191.   /* Now the <tu> nets are represented by only <bu> models*/
  192.  
  193.                   /* Apply a little randomic mutation         */
  194.   for (i=bu+1;i<=tu;i++)
  195.   {
  196.    nu=un[i].nr;
  197.    for (in=1;in<=NL0+NL1+NL2;in++)
  198.    {
  199.     rnconn(nu,in,&tc);
  200.     for (jc=0;jc<tc;jc++)              /* note that link <jc> start from 0 */
  201.     {rconn(nu,in,jc,&weigt,&node);
  202.      weigt=weigt+frndab(-.1,.1);
  203.      wwgt(nu,in,jc,weigt); }
  204.    }
  205.   }
  206.   /* Now we have a new generation */
  207. }
  208.  
  209. end()
  210. {
  211.  cancnets();
  212.  exit(0);
  213. }
  214.  
  215. help()
  216. {
  217.  printf("\n NET TRAINING WITH GENETIC ALGORITM \n");
  218.  printf("\n parameters: ");
  219.  printf("\n    /tu=.. : total nets (def = 100)");
  220.  printf("\n    /tg=.. : total generations (def = 300)");
  221.  printf("\n ");
  222. }
  223.  
  224.  
  225. rndab(int a,int b)           /* Integer random value between a and b        */
  226. {
  227.   float num;
  228.   num= rand()&0x7FFF; num=num/MAX_RAND;
  229.   return (floor)(num*(b-a)+a+.5);
  230. }
  231.  
  232. float frndab(float a,float b)        /* Float random between a and b */
  233. {
  234.   float num;
  235.   num= rand()&0x7FFF; num=num/MAX_RAND;
  236.   return (num*(b-a)+a);
  237. }
  238.  
  239. listsort(struct un vet[],int dim)    /* Sort in ascendig order of vet[].err*/
  240. {
  241.   int c,i,appo2;
  242.   float appo1;
  243.   for (c=1; c<=dim; c++)
  244.   {
  245.     for (i=dim;i>c;i--)
  246.     {
  247.     if (vet[i].err < vet[i-1].err)
  248.     { appo1=vet[i].err; vet[i].err=vet[i-1].err; vet[i-1].err=appo1;
  249.       appo2=vet[i].nr; vet[i].nr=vet[i-1].nr; vet[i-1].nr=appo2;   }
  250.     }
  251.   }
  252. }
  253.  
  254.